/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LOW_LEVEL_H
#define __LOW_LEVEL_H

#ifndef __ODRIVE_MAIN_H
#error "This file should not be included directly. Include odrive_main.h instead."
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <cmsis_os.h>
#include <stdbool.h>
#include <adc.h>

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define ADC_CHANNEL_COUNT 16
extern const float adc_full_scale;
extern const float adc_ref_voltage;
/* Exported variables --------------------------------------------------------*/
extern float vbus_voltage;
extern float ibus_;
extern bool brake_resistor_armed;
extern bool brake_resistor_saturated;
extern uint16_t adc_measurements_[ADC_CHANNEL_COUNT];
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

typedef struct{   
	uint8_t   ucFinishFlag;
    uint8_t   ucStartFlag;
    uint32_t  usLowPulse;
    uint32_t  usHighPulse;
	uint32_t  usCtr;
	uint32_t  usPeriod;
}STRUCT_CAPTURE;



void safety_critical_arm_motor_pwm(Motor& motor);
bool safety_critical_disarm_motor_pwm(Motor& motor);
void safety_critical_apply_motor_pwm_timings(Motor& motor, uint16_t timings[3]);
void safety_critical_arm_brake_resistor();
void safety_critical_disarm_brake_resistor();
void safety_critical_apply_brake_resistor_timings(uint32_t low_off, uint32_t high_on);

// called from board platform code
extern "C" {
void pwm_trig_adc_cb(uint32_t adc_periph, bool injected);
void vbus_sense_adc_cb(uint32_t adc_periph, bool injected);
void tim_update_cb(uint32_t timer_periph);
void pwm_in_enc_cb(uint8_t m0_m1,int channel, uint32_t timestamp);
}

// 初始化
void start_adc_pwm();
void start_pwm(uint32_t timer_periph);
void sync_timers(uint32_t tim_a, uint32_t tim_b,
                 uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset);
void start_general_purpose_adc();
void update_brake_current();

inline uint32_t cpu_enter_critical() {
    uint32_t primask = __get_PRIMASK();
    __disable_irq();
    return primask;
}

inline void cpu_exit_critical(uint32_t priority_mask) {
    __set_PRIMASK(priority_mask);
}

#ifdef __cplusplus
}
#endif



#endif //__LOW_LEVEL_H

